package org.softmed.rest.editor.comps.browser;



import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.AbstractTableModel;

import org.softmed.reflection.utils.FieldInfo;
import org.softmed.reflection.utils.ReflectionUtil;

public class ReflectionTableModel extends AbstractTableModel {

    ReflectionUtil util = new ReflectionUtil();
    List<Object> list = new ArrayList<Object>();
    List<String> fields = new ArrayList<String>();
    List<String> columnTitle = new ArrayList<String>();
    Map<String, FieldInfo> fieldInfos = new HashMap<String, FieldInfo>();

    public void clear() {
        list.clear();
        fields.clear();
        fieldInfos.clear();
        columnTitle.clear();
    }

    public void prepare(Class type) throws Throwable {


        List<FieldInfo> infos = util.getFieldInfos(type);
        for (FieldInfo fieldInfo : infos) {
            fieldInfos.put(fieldInfo.getName(), fieldInfo);
        }

    }

    public void useAllFieldNamesAsColumns() {
        fields.addAll(fieldInfos.keySet());
        columnTitle.addAll(fieldInfos.keySet());
    }

    @Override
    public int getRowCount() {
        return list.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Object object = list.get(rowIndex);
        String fieldName = fields.get(columnIndex);

        return getReflectonFieldName(object,fieldName);
       
//        FieldInfo fieldInfo = fieldInfos.get(fieldName);
//        Object value = null;
//        try {
//            value = fieldInfo.getGetter().invoke(object, null);
//        } catch (Throwable e) {
//            e.printStackTrace();
//        }
//        return value;
    }

    protected Object getReflectonFieldName(Object object, String field) {
        try {
            String fieldName = field;
            Object child;
            if (fieldName.contains(".")) {

                String firstFieldName = fieldName.substring(0, fieldName.indexOf('.'));
                System.out.println("Getting fieldName: " + firstFieldName);
                String rest = fieldName.substring(fieldName.indexOf('.') + 1);
                System.out.println("Rest of  fieldName: " + rest);

                child = util.getFieldValue(object, firstFieldName);
                return getReflectonFieldName(child, rest);

            }
            
            return util.getFieldValue(object, fieldName);

        } catch (Throwable ex) {
            Logger.getLogger(ReflectionTableModel.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    //	public Class getColumnClass(int columnIndex) {
    //		String fieldName = fields.get(columnIndex);
    //		FieldInfo fieldInfo = fieldInfos.get(fieldName);
    //		if (fieldInfo.getType() == boolean.class
    //				|| fieldInfo.getType() == Boolean.class)
    //			return boolean.class;
    //
    //		else
    //
    //			return String.class;
    //	}
    public List<Object> getList() {
        return list;
    }

    public List<String> getFields() {
        return fields;
    }

    public List<String> getColumnTitle() {
        return columnTitle;
    }

    public boolean isCellEditable(int row, int col) {
        return false;
    }

    public String getColumnName(int col) {
        return columnTitle.get(col);
    }

    public int getColumnCount() {
        return columnTitle.size();
    }
}
